//
//  TodoItemDemoTests.swift
//  TodoItemDemoTests
//
//  Created by lee tank on 2017/7/31.
//  Copyright © 2017年 RoseVision. All rights reserved.
//

import XCTest
@testable import TodoItemDemo

class TodoItemDemoTests: XCTestCase {
    var controller: LRTableViewController!
    
    override func setUp() {
        super.setUp()
        controller = UIStoryboard(name: "Main", bundle: .main).instantiateViewController(withIdentifier: "TableViewController") as! LRTableViewController
        
        _ = controller.view
        
    }
    
    override func tearDown() {
        // Put teardown code here. This method is called after the invocation of each test method in the class.
        super.tearDown()
    }
    
    func testReducerUpdateTextFromEmpty() {
        let dataSource = TableViewControllerDataSource(todos: [], owner: nil)
        let state = controller.reducer(.updateText(text: "123"), LRTableViewController.State(dataSource: dataSource, text: "")).state
        XCTAssertEqual(state.text, "123")
        
        
    }
    
    func testReducerUpdateTextFromExisting() {
        let dataSource = TableViewControllerDataSource(todos: ["1", "2", "3"], owner: nil)
        let state = controller.reducer(.updateText(text: "123"), LRTableViewController.State(dataSource: dataSource, text: "")).state
        XCTAssertEqual(state.text, "123")
    }
    
    func testReducerUpdateTextToEmpty() {
        let dataSource = TableViewControllerDataSource(todos: ["123"], owner: nil)
        let state = controller.reducer(.updateText(text: ""), LRTableViewController.State(dataSource: dataSource, text: "")).state
        XCTAssertEqual(state.text, "")
    }
    
    func testReducerAddToDos() {
        let dataSource = TableViewControllerDataSource(todos: ["123"], owner: nil)
        let state = controller.reducer(.addTodos(items: ["1", "2", "3"]), LRTableViewController.State(dataSource: dataSource, text: "")).state
        XCTAssertEqual(state.dataSource.todos, ["1", "2", "3", "123"])
    }
    
    func testUpdateView() {
        XCTAssertFalse(controller.navigationItem.rightBarButtonItem!.isEnabled)
        let state1 = LRTableViewController.State(dataSource: TableViewControllerDataSource(todos: [], owner: nil), text: "")
        let state2 = LRTableViewController.State(dataSource: TableViewControllerDataSource(todos: ["1", "2", "3"], owner: nil), text: "hello")
        let state3 = LRTableViewController.State(dataSource: TableViewControllerDataSource(todos: ["hello", "1"], owner: nil), text: "3")
        let state4 = LRTableViewController.State(dataSource: TableViewControllerDataSource(todos: [], owner: nil), text: "L R")
        
        controller.stateDidChanged(state: state2, previousState: state1, command: nil)
        
        XCTAssertEqual(controller.tableView.numberOfRows(inSection: TableViewControllerDataSource.Section.todos.rawValue), 3)
        XCTAssertEqual(controller.tableView.cellForRow(at: todoItemIndexPath(row: 2))?.textLabel?.text, "3")
        XCTAssertEqual(controller.title, "TODO - (3)")
        XCTAssertTrue(controller.navigationItem.rightBarButtonItem!.isEnabled)
        
        controller.stateDidChanged(state: state1, previousState: state2, command: nil)
        XCTAssertEqual(controller.title, "TODO - (0)")
        XCTAssertFalse(controller.navigationItem.rightBarButtonItem!.isEnabled)

    
        controller.stateDidChanged(state: state3, previousState: state2, command: nil)
        XCTAssertEqual(controller.tableView.numberOfRows(inSection: TableViewControllerDataSource.Section.todos.rawValue), 2)
        XCTAssertEqual(controller.tableView.cellForRow(at: todoItemIndexPath(row: 1))?.textLabel?.text, "1")
        XCTAssertEqual(controller.title, "TODO - (2)")
        XCTAssertFalse(controller.navigationItem.rightBarButtonItem!.isEnabled)
        
        
        controller.stateDidChanged(state: state4, previousState: state3, command: nil)
        XCTAssertEqual(controller.tableView.numberOfRows(inSection: TableViewControllerDataSource.Section.todos.rawValue), 0)
        XCTAssertNil(controller.tableView.cellForRow(at: todoItemIndexPath(row: 0)))
        XCTAssertEqual(controller.title, "TODO - (0)")
        XCTAssertTrue(controller.navigationItem.rightBarButtonItem!.isEnabled)
        
        
        
    }
    
    func testRemoveOutOfBounds() {
        let dataSource = TableViewControllerDataSource(todos: ["123"], owner: nil)
        let state = controller.reducer(.removeTodo(index: 2), LRTableViewController.State(dataSource: dataSource, text: "")).state
        XCTAssertEqual(state.dataSource.todos, ["123"])

    }
    
    func testRemove() {
        let dataSource = TableViewControllerDataSource(todos: ["1", "2", "3"], owner: nil)
        let state = controller.reducer(.removeTodo(index: 2), LRTableViewController.State(dataSource: dataSource, text: "")).state
        XCTAssertEqual(state.dataSource.todos, ["1", "2"])
        
    }
    
    func testAdding() {
        let testItem = "Test Item"
        let originalTodos = controller.store.state.dataSource.todos
        controller.store.dispatch(action: .updateText(text: testItem))
        controller.addButtonPressed(self)
        let dataSource = controller.store.state.dataSource
        XCTAssertEqual(dataSource.todos, [testItem] + originalTodos)


    }
    
    func testInputChanged() {
        controller.inputChanged(cell: LRTableViewCell(), text: "123")
        XCTAssertEqual(controller.store.state.text, "123")
    }
    
    func testLoadToDos() {
        let initialState = controller.store.state
        let (_, command) = controller.reducer(.loadToDos, initialState)
        XCTAssertNotNil(command)
        switch command! {
        case .loadToDos(let handler):
            handler(["1", "2"])
            XCTAssertEqual(controller.store.state.dataSource.todos, ["1", "2"])
        default:
            XCTFail("The command should be .loadToDos")

        }
    }
    
    func testPerformanceExample() {
        // This is an example of a performance test case.
        self.measure {
            // Put the code you want to measure the time of here.
        }
    }
    func todoItemIndexPath(row: Int) -> IndexPath {
        return IndexPath(row: row, section: TableViewControllerDataSource.Section.todos.rawValue)
    }
    
}
